package com.dps.metrics.processor;

import com.dps.metrics.mapper.ResultTagMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Callable;

public abstract class AbstractMetricsProcessor implements MetricsRecorder {
    private static final Logger log = LoggerFactory.getLogger(AbstractMetricsProcessor.class);
    protected Long startTime;
    protected Map<String, String> baseTags = new HashMap(1);

    public AbstractMetricsProcessor() {
    }

    public <R> R process(Callable<R> processor, Map<String, String> tags) throws Exception {
        return this.process(processor, tags, (isSuccess, result) -> {
            return null;
        });
    }

    public <R> R process(Callable<R> processor) throws Exception {
        return this.process(processor, (isSuccess, result) -> {
            return null;
        });
    }

    public <R> R process(Callable<R> processor, ResultTagMapper<Object> resultTagMapper) throws Exception {
        return this.process(processor, null, resultTagMapper);
    }


    public <R> R process(Callable<R> processor, Map<String, String> tags, ResultTagMapper<Object> resultTagMapper) throws Exception {
        tags = tags != null && !tags.isEmpty() ? tags : this.baseTags;
        Map<String, String> startFinishTags = new HashMap(tags);
        this.startTime = System.nanoTime();
        this.recordStart(startFinishTags);
        R result = null;
        HashMap recordTags = new HashMap(tags);

        Object var7;
        try {
            result = processor.call();
            this.recordSuccess(recordTags, resultTagMapper, result);
            var7 = result;
        } catch (Exception var11) {
            this.recordFail(recordTags, resultTagMapper, var11);
            throw var11;
        } finally {
            this.startTime = null;
            this.recordFinished(startFinishTags);
        }

        return (R) var7;
    }

    private void recordFail(Map<String, String> tags, ResultTagMapper<Object> resultTagMapper, Exception e) {
        try {
            Map<String, String> resultMap = resultTagMapper.map(false, e);
            if (resultMap != null && !resultMap.isEmpty()) {
                resultMap.putAll(tags);
                this.recordError(resultMap);
            } else {
                this.recordError(tags);
            }
        } catch (Exception var6) {
            log.error("Process error record fail,  cause [{}] ", var6.getMessage());
        }

    }

    private <R> void recordSuccess(Map<String, String> tags, ResultTagMapper<Object> resultTagMapper, R result) {
        try {
            Map<String, String> resultMap = resultTagMapper.map(true, result);
            if (resultMap != null && !resultMap.isEmpty()) {
                resultMap.putAll(tags);
                this.recordSuccess(resultMap);
            } else {
                this.recordSuccess(tags);
            }
        } catch (Exception var6) {
            log.error("Process success record fail,  cause [{}] ", var6.getMessage());
        }

    }


}

